// @Author EthanScriptOn
// @Desc
package connect

import (
	"context"
	"fmt"
	"gitee.com/fatzeng/srf_switch_basic_components/util"
	"gitee.com/fatzeng/srf_switch_expansion_package/detect"
	"github.com/go-redis/redis/v8"
)

var RedisExecDB *util.OnceInitializer

var RedisExecDBChecker = func() (isInvalid bool) {
	consumer, err := generateRedisExecDB()
	if err != nil {
		return true
	}
	ctx := context.Background()
	_, err = consumer.Ping(ctx).Result()
	if err != nil {
		_ = consumer.Close()
		return true
	}
	return false
}

var RedisExecDBRecover = func() (err error) {
	RedisExecDB.Reset()
	_, err = RedisExecDB.Get()
	return err
}

var RedisExecDBMonitor = detect.GenerateResourceMonitor("redis_exec", true, RedisExecDBChecker, RedisExecDBRecover, detect.MonitorFunctionInstance)

func GetRedisExecDB() (producer *redis.Client, err error) {
	defer detect.BackendHealthChecker.AddResource(RedisExecDBMonitor)
	return generateRedisExecDB()
}

func generateRedisExecDB() (consumer *redis.Client, err error) {
	if RedisExecDB == nil {
		return nil, fmt.Errorf("the RedisExecDB initialization required")
	}
	instanceInter, err := RedisExecDB.Get()
	if err != nil {
		return nil, err
	}
	instance, ok := instanceInter.(*redis.Client)
	if !ok {
		return nil, fmt.Errorf("the instance is not of type redis.Client")
	}
	return instance, nil
}

var RedisQueryDB *util.OnceInitializer

var RedisQueryDBChecker = func() (isInvalid bool) {
	consumer, err := generateRedisQueryDB()
	if err != nil {
		return true
	}
	ctx := context.Background()
	_, err = consumer.Ping(ctx).Result()
	if err != nil {
		_ = consumer.Close()
		return true
	}
	return false
}

var RedisQueryDBRecover = func() (err error) {
	RedisQueryDB.Reset()
	_, err = RedisQueryDB.Get()
	return err
}

var RedisQueryDBMonitor = detect.GenerateResourceMonitor("redis_query", true, RedisQueryDBChecker, RedisQueryDBRecover, detect.MonitorFunctionInstance)

func GetRedisQueryDB() (consumer *redis.Client, err error) {
	defer detect.BackendHealthChecker.AddResource(RedisQueryDBMonitor)
	return generateRedisQueryDB()
}

func generateRedisQueryDB() (consumer *redis.Client, err error) {
	if RedisQueryDB == nil {
		return nil, fmt.Errorf("the RedisQueryDB initialization required")
	}
	instanceInter, err := RedisQueryDB.Get()
	if err != nil {
		return nil, err
	}
	instance, ok := instanceInter.(*redis.Client)
	if !ok {
		return nil, fmt.Errorf("the instance is not of type redis.Client")
	}
	return instance, nil
}
